home *** CD-ROM | disk | FTP | other *** search
- /*
- ==============================================================================
- WordUp Graphics Toolkit Version 5.0
- Demonstration Program 42
-
- Demonstrates the polygon routines available. It rotates a triangle
- in the middle of the screen using either a hollow, solid or Gouraud shaded
- polygon. Also introduced is the dirty rectangle method of updating the
- screen.
-
- Once the first three polygon methods are shown, a textured mapped polygon
- is shown.
-
- *** PROJECT ***
- This program requires the file WGT5_WC.LIB to be linked.
-
- *** DATA FILES ***
- TEXTMAP.CEL must be in your executable directory.
- WATCOM C++ VERSION
- ==============================================================================
- */
-
- #include <math.h>
- #include <wgt5.h>
-
- short num_sides; /* Number of sides for the current polygon.
- For the first loop this is 3, and the second
- loop it is 4. */
-
- short polytype; /* Current polygon type to draw */
- short currot; /* Current rotation of the triangle */
-
- short isin[360]; /* Sin values 0-360, multiplied by 1024 */
- short icos[360]; /* Cos values 0-360, multiplied by 1024 */
-
- typedef struct { /* Dirty rectangle structure */
- short x1;
- short y1;
- short x2;
- short y2; /* Keeps track of which area on the screen */
- } rect; /* has been changed */
- rect lastrect; /* Dirty rectangle for last frame */
- rect thisrect; /* Dirty rectangle for current frame */
-
- tpolypoint plainpoly[4]; /* Holds polygon points before rotation */
- tpolypoint rotatedpoly[4]; /* After rotation */
-
- color pal[256];
- short oldmode;
- block other; /* A background page for dirty rectangles */
- block texturemap; /* A texture bitmap (128x128) */
- short square_size; /* Size of the texture mapped square */
- short size_dir; /* 1 or -1, added to square_size */
-
-
- void clear_last(void)
- {
- /* Do clipping for smallest area update */
- if (lastrect.x1 < 0)
- lastrect.x1 = 0;
- if (lastrect.x2 > 319)
- lastrect.x2 = 319;
- if (lastrect.y1 < 0)
- lastrect.y1 = 0;
- if (lastrect.y2 > 199)
- lastrect.y2 = 199;
- wsetcolor (0);
- wbar (lastrect.x1, lastrect.y1, lastrect.x2, lastrect.y2);
- /* Clear out the area that was drawn in last frame */
- }
-
-
- void update_screen(void)
- {
- if (lastrect.x1 > thisrect.x1)
- lastrect.x1 = thisrect.x1;
- if (lastrect.x2 < thisrect.x2)
- lastrect.x2 = thisrect.x2;
- if (lastrect.y1 > thisrect.y1)
- lastrect.y1 = thisrect.y1;
- if (lastrect.y2 < thisrect.y2)
- lastrect.y2 = thisrect.y2;
- /* See if the previous frame was larger in any direction. If it is, enlarge
- the area so it will copy black over the previous frame. */
-
- /* Do clipping */
- if (lastrect.x1 < 0)
- lastrect.x1 = 0;
- if (lastrect.x2 > 319)
- lastrect.x2 = 319;
- if (lastrect.y1 < 0)
- lastrect.y1 = 0;
- if (lastrect.y2 > 199)
- lastrect.y2 = 199;
-
- wcopyscreen(lastrect.x1, lastrect.y1, lastrect.x2, lastrect.y2, other,
- lastrect.x1, lastrect.y1, NULL);
- /* Copy from our second page to the visual page. */
-
- lastrect.x1 = thisrect.x1;
- lastrect.y1 = thisrect.y1;
- lastrect.x2 = thisrect.x2;
- lastrect.y2 = thisrect.y2;
- /* Make the last rectangle = current rectangle */
- }
-
-
- void makesin_cos_tables (void)
- /* Calculates the tables for our 2D rotation */
- {
- short i;
-
- for (i = 0; i < 360; i++)
- {
- isin[i] = sin(3.1415 * ((double)i / 180.0)) * 1024;
- icos[i] = cos(3.1415 * ((double)i / 180.0)) * 1024;
- }
- }
-
-
- void rotatepoly (short cnx, short cny, tpolypoint *plain, tpolypoint *rotated,
- short numpoints, short rotation)
- /* Rotates a set of polygon points, given the center of the polygon, number
- of points, and the rotation in degrees. The points to be rotated are in
- "plain", and the new points are stored in "rotated". */
- {
- short i;
- short x, y;
- short x2, y2;
-
- for (i = 0; i < numpoints; i++)
- {
- x = plain[i].x - cnx;
- y = plain[i].y - cny;
-
- x2 = ((int)x * icos[rotation] - (int)y * isin[rotation]) >> 10;
- y2 = ((int)x * isin[rotation] + (int)y * icos[rotation]) >> 10;
- rotated[i].x = x2 + cnx;
- rotated[i].y = y2 + cny;
- rotated[i].sx = plain[i].sx;
- rotated[i].sy = plain[i].sy;
- }
- }
-
-
- void make_triangle (void)
- /* Set up some points to make a triangle */
- {
- plainpoly[0].x = 160;
- plainpoly[0].y = 60;
- plainpoly[0].sx = 5;
-
- plainpoly[1].x = 120;
- plainpoly[1].y = 140;
- plainpoly[1].sx = 50;
-
- plainpoly[2].x = 200;
- plainpoly[2].y = 140;
- plainpoly[2].sx = 100;
- }
-
-
- void make_square (void)
- /* Set up some points to make a square */
- {
- plainpoly[0].x = 160 - square_size;
- plainpoly[0].y = 100 - square_size;
- plainpoly[0].sx = 0; /* This sets the offset into the texture bitmap */
- plainpoly[0].sy = 0;
-
- plainpoly[1].x = 160 + square_size;
- plainpoly[1].y = 100 - square_size;
- plainpoly[1].sx = 127;
- plainpoly[1].sy = 0;
-
- plainpoly[2].x = 160 + square_size;
- plainpoly[2].y = 100 + square_size;
- plainpoly[2].sx = 127;
- plainpoly[2].sy = 127;
-
- plainpoly[3].x = 160 - square_size;
- plainpoly[3].y = 100 + square_size;
- plainpoly[3].sx = 0;
- plainpoly[3].sy = 127;
- }
-
-
- void make_palette (void)
- /* Make a shaded palette for Gouraud shading */
- {
- short i;
-
- for (i = 0; i < 64; i++)
- {
- wsetrgb (i, 0, i / 2, i, pal);
- wsetrgb (i + 64, i, (63 - i) / 2, (63 - i), pal);
- }
- wsetrgb (1, 63, 63, 63, pal);
- wsetpalette (0, 255, pal);
- }
-
-
- void find_edges (void)
- /* Scans through all points in the polygon, and sees if the dirty rectangle
- area should be increased to include the point. */
- {
- short i;
-
- for (i = 0; i < num_sides; i++)
- {
- if (rotatedpoly[i].x < thisrect.x1)
- thisrect.x1 = rotatedpoly[i].x;
- if (rotatedpoly[i].x > thisrect.x2)
- thisrect.x2 = rotatedpoly[i].x;
- if (rotatedpoly[i].y < thisrect.y1)
- thisrect.y1 = rotatedpoly[i].y;
- if (rotatedpoly[i].y > thisrect.y2)
- thisrect.y2 = rotatedpoly[i].y;
- /* See if the polygon is larger than the current area to update.
- If it is, enlarge the area so all polygons fit inside. */
- }
- }
-
-
- void main(void)
- {
- oldmode = wgetmode ();
-
- printf ("WGT Example #42\n\n");
- printf ("Polygons and texture-mapping are demonstrated using some optimized dirty-\n");
- printf ("rectangle code. Press a key to advance to the next type of polygon.\n");
- printf ("\n\nPress any key to continue.\n");
- getch ();
-
- vga256();
- other = wnewblock (0, 0, 319, 199);
- winitpoly (WGT_SYS.yres);
- makesin_cos_tables ();
- make_palette ();
- make_triangle ();
-
- wsetscreen (other);
- lastrect.x1 = 0;
- lastrect.y1 = 0;
- lastrect.x2 = 319;
- lastrect.y2 = 199;
- currot = 0;
- num_sides = 3;
-
- do {
- thisrect.x1 = 319;
- thisrect.y1 = 199;
- thisrect.x2 = 0;
- thisrect.y2 = 0;
- clear_last ();
- rotatepoly (160, 100, plainpoly, rotatedpoly, num_sides, currot);
-
- find_edges ();
-
- wsetcolor (60);
- switch (polytype)
- {
- case 0: whollowpoly (rotatedpoly, num_sides, 0, 0, CLOSED_POLY);
- break;
- case 1: wsolidpoly (rotatedpoly, num_sides, 0, 0, NULL);
- break;
- case 2: wgouraudpoly (rotatedpoly, num_sides, 0, 0);
- break;
- }
- update_screen ();
-
- currot++; /* Rotate the polygon */
- if (currot > 359)
- currot -= 360;
-
- if (kbhit ())
- {
- getch ();
- polytype++; /* Go to the next type of polygon */
- }
- } while (polytype < 3);
-
- /* Now do a texture mapped polygon */
- num_sides = 4;
- make_square ();
- wcls (0);
- lastrect.x1 = 0;
- lastrect.y1 = 0;
- lastrect.x2 = 319;
- lastrect.y2 = 199;
- currot = 0;
- texturemap = wloadcel ("textmap.cel", pal);
- wsetpalette (0, 255, pal);
- square_size = 63;
- size_dir = -1;
-
- do {
- thisrect.x1 = 319;
- thisrect.y1 = 199;
- thisrect.x2 = 0;
- thisrect.y2 = 0;
-
- square_size += size_dir;
- if (square_size < 30) /* Make the polygon get bigger and smaller */
- size_dir = 1;
- if (square_size > 100)
- size_dir = -1;
- make_square ();
-
- clear_last ();
- rotatepoly (160, 100, plainpoly, rotatedpoly, num_sides, currot);
- find_edges ();
-
- wtexturedpoly (rotatedpoly, num_sides, 0, 0, texturemap, NORMAL);
- update_screen ();
-
- currot += 3 * size_dir; /* Rotate the polygon */
- if (currot > 359)
- currot -= 360;
- if (currot < 0)
- currot += 360;
- } while (!kbhit ());
- wdeinitpoly ();
- wfreeblock (other);
- wfreeblock (texturemap);
- wsetmode (oldmode);
- }
-